//-------------------------------------------------------------------------------------
// <copyright file="ReceiveHandler.cs" company="Microsoft">
//      Copyright (c) 2003 Microsoft Corporation. All rights reserved.
//      THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND, 
//      EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED 
//      WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
// </copyright>
// <summary>
//      Represents a receive handler, which acts as a container for the handlers of the adapter.
// </summary>  
//-------------------------------------------------------------------------------------

namespace Microsoft.Sdc.Tasks.BizTalk2004.Configuration
{
	#region Using directives 

	using System;
	using System.Management;

	#endregion 

	/// <summary>
	/// Represents a receive handler, which acts as a container for the handlers of the adapter.
	/// </summary>
	internal class ReceiveHandler : BizTalkNonConfigurableEntityBase
	{
		#region Member variables

		private Host host;
		private Protocol transportType;
		private ReceiveLocation receiveLocation;

		#endregion 

		#region Properties

		/// <summary>
		/// Gets the <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.Host"/> to which the receive handler is associated. 
		/// </summary>
		/// <value>A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.Host"/> object.</value>
		public Host Host
		{
			get { return this.host;}
		}

		/// <summary>
		/// Gets the transport type for the receive handler.
		/// </summary>
		/// <value> A <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.Protocol"/> object. </value>
		public Protocol TransportType
		{
			get {return this.transportType;}
		}


		#endregion 


		#region methods 

		/// <summary>
		/// Creates a new Receive Handler instance. This is private because instance of this class can only be created with
		/// the Load method.
		/// </summary>
		/// <param name="receiveLocation"> The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceiveLocation"/> of this receive handler.</param>
		/// <param name="name">The name of this receive handler.</param>
		private ReceiveHandler(ReceiveLocation receiveLocation, string name): base(receiveLocation.Installation, name){
		
			this.receiveLocation = receiveLocation;
		}


		/// <summary>
		/// Creates a new Receive Handler instance. This is private because instance of this class can only be created with
		/// the Load method.
		/// </summary>
        /// <param name="installation"> The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.BizTalkInstallation"/> of this receive handler.</param>
		/// <param name="name">The name of this receive handler.</param>
		private ReceiveHandler(BizTalkInstallation installation, string name): base(installation, name){}


		/// <summary>
		/// Loads the details of a Receive Handler
		/// </summary>
		/// <param name="installation"> The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.BizTalkInstallation"/> of this receive handler.</param>
		/// <param name="name">The name of this receive handler.</param>
		/// <param name="transportName">The transport name, e.g. FILE of SQL</param>
		/// <returns></returns>
		public static ReceiveHandler Load(BizTalkInstallation installation, string name, string transportName)
		{
			//check inputs
			if (installation == null) throw new ArgumentException("installation");
			if (name == null || name.Length == 0) throw new ArgumentException("name");

			BtsReceiveHandler rxHandler = ReceiveHandler.GetActualReceiveHandler(installation, name, transportName);

			ReceiveHandler receiveHandler = null;
			if (rxHandler != null)
			{
				receiveHandler = new ReceiveHandler(installation, name);
				receiveHandler.host = Host.Load(receiveHandler.Installation, rxHandler.Host.Name);
				receiveHandler.transportType  = Protocol.Load(receiveHandler.Installation, rxHandler.TransportType.Name);
			}
			return receiveHandler;
		}


		/// <summary>
		/// Loads the details of a Receive Handler
		/// </summary>
		/// <param name="receiveLocation"> The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.ReceiveLocation"/> of this receive handler.</param>
		/// <param name="name">The name of this receive handler.</param>
		/// <param name="transportName">The transport name, e.g. FILE of SQL</param>
		/// <returns></returns>
		public static ReceiveHandler Load(ReceiveLocation receiveLocation, string name, string transportName)
		{
			//check inputs
			if (receiveLocation == null) throw new ArgumentException("receiveLocation");
			if (name == null || name.Length == 0) throw new ArgumentException("name");

			BtsReceiveHandler rxHandler = ReceiveHandler.GetActualReceiveHandler(receiveLocation.Installation, name, transportName);

			ReceiveHandler receiveHandler = null;
			if (rxHandler != null)
			{
				receiveHandler = new ReceiveHandler(receiveLocation, name);
				receiveHandler.host = Host.Load(receiveHandler.Installation, rxHandler.Host.Name);
				receiveHandler.transportType  = Protocol.Load(receiveHandler.Installation, rxHandler.TransportType.Name);
			}
			return receiveHandler;

		}

		
		/// <summary>
		/// Gets the actual ReceiveHandler object that is deployed in BizTalk.
		/// </summary>
		/// <param name="installation">The <see cref="Microsoft.Sdc.Tasks.BizTalk2004.Configuration.BizTalkInstallation"/> object that contains this ReceiveHandler. </param>
		/// <param name="name">The name of the ReceiveHandler to load.</param>
		/// <param name="transportName">The transport name, e.g. FILE of SQL</param>
		/// <returns> a <see cref="BtsReceiveHandler"/> object. </returns>
		private static BtsReceiveHandler GetActualReceiveHandler(BizTalkInstallation installation, string name, string transportName)
		{
			BtsReceiveHandler rxHandler = null;
			foreach(BtsReceiveHandler handler in installation.CatalogExplorer.ReceiveHandlers)
			{
				if (handler.Name == name && handler.TransportType.Name == transportName)
				{
					rxHandler = handler;
					break;
				}

			}
			return rxHandler;

		}
		
		public static void MoveHost(BizTalkInstallation installation, string transportType, string newHostName)
		{
			MoveHost(installation, transportType, newHostName, string.Empty);
		}

		public static void MoveHost(BizTalkInstallation installation, string transportType, string newHostName, string oldHostName)
		{
			try
			{
				PutOptions options = new PutOptions();
				options.Type = PutType.UpdateOnly;

				//Look for the target WMI Class MSBTS_ReceiveHandler instance
				string query;
				if (oldHostName != null && oldHostName.Length > 0)
				{
					query = "SELECT * FROM MSBTS_ReceiveHandler WHERE AdapterName =\"" + transportType + "\" AND HostName = \"" + oldHostName + "\"";
				}
				else
				{
					query = "SELECT * FROM MSBTS_ReceiveHandler WHERE AdapterName =\"" + transportType + "\"";
				}
				ManagementScope scope = ManagementHelper.GetManagementScope(installation);
				ManagementObjectSearcher searcherReceiveHandler = new ManagementObjectSearcher (scope, new WqlObjectQuery(query), null);
   
				if (searcherReceiveHandler.Get().Count > 0)
				{
					foreach (ManagementObject objReceiveHandler in searcherReceiveHandler.Get())
					{
						//update host association
						objReceiveHandler["HostNameToSwitchTo"] = newHostName;
						//update the ManagementObject
						objReceiveHandler.Put(options);
						System.Diagnostics.Trace.WriteLine("ReceiveHandler - " + transportType + " " + newHostName + " - has been updated successfully");
					}
				}
				else
				{
					System.Console.WriteLine("ReceiveHandler - " + transportType + " - cannot be found");               
				}
			}
			catch(Exception ex)
			{
				System.Diagnostics.Trace.WriteLine("ReceiveHandler - " + transportType + " - failed: " + ex.Message);
				throw;
			}
		}

        public static void AddNew(BizTalkInstallation installation, string transportType, string hostName, string customConfig)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine(string.Format("Adding new receive handler '{0}' to host '{1}'", transportType, hostName));
                PutOptions options = new PutOptions();
                options.Type = PutType.CreateOnly;

                //ManagementScope scope = ManagementHelper.GetManagementScope(installation);
                ManagementClass receiveHandlerClass = ManagementHelper.GetManagementClass(installation, "MSBTS_ReceiveHandler");

                ManagementObject recObj = receiveHandlerClass.CreateInstance();
                recObj["AdapterName"] = transportType;
                recObj["HostName"] = hostName;
                if (customConfig != null && customConfig.Length > 0)
                {
                    recObj["CustomCfg"] = customConfig;
                }

                recObj.Put(options);

            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine("Add Host for ReceiveHandler - " + transportType + " - failed: " + ex.Message);
                throw;
            }
        }

        public static void Delete(BizTalkInstallation installation, string transportType, string hostName)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine(string.Format("Deleting receive handler '{0}' on host '{1}'...",
                    transportType, hostName));

                string query = "SELECT * FROM MSBTS_ReceiveHandler WHERE AdapterName =\"" + transportType + "\" AND HostName = \"" + hostName + "\"";
                ManagementScope scope = ManagementHelper.GetManagementScope(installation);
                ManagementObjectSearcher searcherReceiveHandler = new ManagementObjectSearcher(scope, new WqlObjectQuery(query), null);

                if (searcherReceiveHandler.Get().Count > 0)
                {
                    foreach (ManagementObject objReceiveHandler in searcherReceiveHandler.Get())
                    {
                        objReceiveHandler.Delete();
                        System.Diagnostics.Trace.WriteLine("ReceiveHandler - " + transportType + " " + hostName + " - has been deleted successfully");
                    }
                }


            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine("Delete ReceiveHandler - " + transportType + " - failed: " + ex.Message);
                throw;

            }

        }

        public static bool Exists(BizTalkInstallation installation, string hostName, string transportType)
        {
            try
            {
                System.Diagnostics.Trace.WriteLine(string.Format("Deleting receive handler '{0}' on host '{1}'...",
                    transportType, hostName));

                string query = "SELECT * FROM MSBTS_ReceiveHandler WHERE AdapterName =\"" + transportType + "\" AND HostName = \"" + hostName + "\"";
                ManagementScope scope = ManagementHelper.GetManagementScope(installation);
                ManagementObjectSearcher searcherReceiveHandler = new ManagementObjectSearcher(scope, new WqlObjectQuery(query), null);

                if (searcherReceiveHandler.Get().Count > 0)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                System.Diagnostics.Trace.WriteLine("Checking for the existance of ReceiveHandler - " + transportType + " - failed: " + ex.Message);
                throw;

            }

        }
		
		#endregion 

	}
}

